package br.com.firula.web.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.interceptor.SessionAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import br.com.firula.bo.UsuarioBO;
import br.com.firula.to.AdministradorTO;
import br.com.firula.to.UsuarioTO;

@SuppressWarnings("unchecked")
public class SecurityFilter implements Filter, SessionAware {
	
	private int NAO_AUTORIZADO = 0;
	private int AUTORIZADO = 1;
	private int SAIR = 2;
	private int LOGIN = 3;
	private int ERRO_LOGIN = 4;
	private int ERRO_LOGIN_INATIVO = 5;
	private int ERRO_REPETIDO = 6;
	private int ADM_PERMISSAO_RESTRITA = 7; // Status indica que o administrador foi logado, porem, como tem permissoes restritas e nao pode acessar a pagina requisitada.
	private int LOGIN_ADM = 8;
	private Map session;

	private static final Map<String, Map<String, String>> HTTP_PARCERIA;
	private static final Map<String, Map<String, String>> HTTPS_PARCERIA;
    static {
    	// Inicia o mapa com as infos das parcerias
    	Map<String, String> aux;
        Map<String, Map<String, String>> pMap = new HashMap<String, Map<String, String>>();
        Map<String, Map<String, String>> sMap = new HashMap<String, Map<String, String>>();
        
        /* MMM - null � quando n�o tem parceria */
        // padrao
        aux = new HashMap<String, String>();
        aux.put("scheme", "http");
        aux.put("name", "www.isnow.com.br");
        aux.put("port", "80");
        pMap.put(null, aux);
        // seguro
        aux = new HashMap<String, String>();
        aux.put("scheme", "https");
        aux.put("name", "www.isnow.com.br");
        aux.put("port", "443");
        sMap.put(null, aux);
        
        /* Minha casa */
        // padrao
        aux = new HashMap<String, String>();
        aux.put("scheme", "http");
        aux.put("name", "www.lojaminhacasa.com.br");
//      aux.put("name", "www.isnow.com.br"); // usar esta opcao se a parceria nao tiver dominio proprio (com alias apontando o mesmo tomcat) 
        aux.put("port", "80");
        pMap.put("minhacasa", aux);
        // seguro
        aux = new HashMap<String, String>();
        aux.put("scheme", "https");
        aux.put("name", "www.isnow.com.br");
        aux.put("port", "443");
        sMap.put("minhacasa", aux);
        
        HTTP_PARCERIA = pMap;
        HTTPS_PARCERIA = sMap;        
    }
    
	private Properties securityMapping = null;
	private UsuarioBO mgr = null;
//	private ClienteBO mgrCliente = null;
//	private PedidoBO mgrPedido = null;
	
	private static final Set<String> redirectLogin = new HashSet<String>();
	private static final Set<String> redirectAfiliado = new HashSet<String>();
	
	static{
		redirectLogin.add("/execute_Painel.html");
		redirectLogin.add("/meusPedidos_Loja.html"); 
		redirectLogin.add("/edit_ClienteLoja.html"); 
		redirectLogin.add("/fecharPedido_Loja.html");
		redirectLogin.add("/logar_DepoimentoLoja.html");
		redirectLogin.add("/login_Loja.html");
		redirectLogin.add("/indexLogado_Loja.html");
		redirectLogin.add("/programaFidelidade_Loja.html");
		redirectLogin.add("/adicionarListaDesejos_Loja.html");
		redirectLogin.add("/visualizarListaDesejos_Loja.html");
		redirectLogin.add("/escolhaCreche_Loja.html");
		redirectLogin.add("/cartaoMadeira_Loja.html");
		redirectLogin.add("/recomendacaoAbraco_Loja.html");
		redirectAfiliado.add("/edit_AfiliadoLoja.html");	
		redirectAfiliado.add("/view_AfiliadoLoja.html");	
		redirectAfiliado.add("/relatorio_AfiliadoLoja.html");
		redirectAfiliado.add("/pontos_AfiliadoLoja.html");
		redirectAfiliado.add("/relatorio_AfiliadoLoja.html");
		redirectAfiliado.add("/inserePontoAfiliado_AfiliadoLoja.html");
		redirectAfiliado.add("/excluiPontoAjax_AfiliadoLoja.html");
		redirectAfiliado.add("/instrucoes_AfiliadoLoja.html");
	}
	
//	@Autowired
//	public void setClienteBO(ClienteBO clienteBO) {
//		this.mgrCliente = clienteBO;
//	}
//	
//	@Autowired
//	public void setPedidoBO(PedidoBO pedidoBO) {
//		this.mgrPedido = pedidoBO;
//	}
	
	public Map getSession() {
		return session;
	}
    
	public void setSession(Map session) {
		this.session = session;
	}
	
	private String getRedir(String path){
		path = path.replace("/minhacasa", "");
		if(redirectLogin.contains(path)){
			return "login_LoginLoja.html";
		}
		if(redirectAfiliado.contains(path)){
			return "login_AfiliadoLoja.html";
		}
		System.out.println("redirected path: " + path);
		return "timeoutRedirectLogin_LoginLoja.html";
	}
	
	public void init(FilterConfig filterConfig) throws ServletException {
		try {
			securityMapping = new Properties();
			securityMapping.load(SecurityFilter.class.getResourceAsStream("/roles.properties"));

			WebApplicationContext  wac = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
//			mgr = (UsuarioBO)wac.getBean("usuarioBO");
//			mgrCliente = (ClienteBO)wac.getBean("clienteBO");
//			mgrPedido = (PedidoBO)wac.getBean("pedidoBO");
		}catch(Exception ignoredForNow) {
			ignoredForNow.printStackTrace();
		}
	}
	
	public void destroy() {
	}

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		HttpSession session = request.getSession();
		Map<String, String> ctx = new HashMap<String, String>();
		// Nesse ponto todas as requisi��es entram;
		defineCTX(request, ctx); // Aqui s�o criadas as entradas do "ctx" para futuras verifica��es, facilitando a passagem de vari�veis;
		if(useSecurityRedirect(ctx)){ // Verifica se a requisi��o deve usar o redirecionamento;
			if(redirect(response, ctx)) // Verifica se deve ser redirecionada e faz ajustes necess�rios (http -> https / https -> http / m.com.br -> www.m.com.br);
				return; // Esse return serve para executar o redirecionamento criado no metodo redirect();
		}
		// Requisi��o est� OK, n�o precisa ser redirecionada;
		if(!useSecurityFilter(ctx)){ // Verifica se deve usar o securityFilter (se � ou n�o .html);
			chain.doFilter(request, response); // Continua a corrente de filtros sem passar pelo securityFilter.
			return;
		}
		
		// XXX Tentativa desesperada de n�o chachear nenhuma p�gina .html, ser� que funciona?
		response.setHeader("Cache-Control", "no-cache");
	    response.setHeader("Pragma", "no-cache");
	    response.setDateHeader("Expires", 0);
		
	    /* FIXME 1 
	     * Misc de coisas que n�o foram alteradas, apenas separadas.
	     * Tirar de dentro desse FIX depois de verificar sua utilidade.
	     * */
	    miscOsklen(request); // Misc de coisas da Osklen
	    miscApple(request); // Misc de coisas para aparelhos Apple (iPhone, iPad, etc)
	    miscAbraco(request); //  Misc do programa de recomenda��o abra�o; XXX Vamos remover j� que n�o usa?
	    if(miscAcessoAdmCliente(request, response, ctx)){ // Misc para login duplo, precisa de redirect na parceria minhacasa
	    	response.sendRedirect(montaURL(ctx));
	    	return;
	    }
	    /* FIXME 1 */
	    
	    /* FIXME 2 
	     * Apagar e repensar, colocar dentro do redirect() sempre setando o atributo pra saber de onde veio e pra onde vai.
		//LUCAS 23/09/08
		String redirAjax = request.getParameter("redirAjax");
		if("true".equals(redirAjax)){
			request.getSession().setAttribute("destino", "/index.html");
		}
		   FIXME 2 */
		
	    String actionString = request.getParameter("action"); // FIXME 3 Remover, pensar em outra coisa.
		int status = defineStatus(request, response);
		
		/* FIXME 4
		 * Colocar dentro de uma fun��o, trataStatus(), ou n�o, pensar sobre isso.
		 * */
		if (status == SAIR) {
			/* FIXME 4.1
			 * Arrumar aqui, pensar em uma maneira mais inteligente e clara de ir pro index.
			 * */
			ctx.put("path", "/");
			ctx.put("query", "");
			response.sendRedirect(montaURL(ctx));
			return;
			/* FIXME 4.1 */
		}else if (status == NAO_AUTORIZADO || status == ERRO_LOGIN || status == ERRO_LOGIN_INATIVO || status == ERRO_REPETIDO) { // TODO muda isso pra um else, bem mais inteligente.
			/* FIXME 4.2
			 * Tem que dar uma entendida nesse c�digo, n�o tenho a menor ideia de como arrumar.
			 * */
			if(request.getSession().getAttribute("PASSOS")!=null && "1".equals(request.getSession().getAttribute("PASSOS")+"") && request.getSession().getAttribute("PEDIDO")!=null) // XXX Pra que serve isso?
				request.getSession().setAttribute("PASSOS", 2);
			
			String redir = "";
			//PopIn de login no carrinho (pontos ammmigo)
			if (request.getServletPath().contains("autenticaAmmmigo")){
				redir = "comprarAgora_Loja.html?login";
				if( status == ERRO_LOGIN ){
					redir +="&erro";
				}else if( status == ERRO_LOGIN_INATIVO ){
					redir +="&inativo";
				}else if( status == ERRO_REPETIDO){
					redir +="&repetido";
				}else {
					redir = getRedir(request.getServletPath())+(request.getQueryString() != null ? "?" + request.getQueryString() : "");
				}
			} 
			else{
				if( status == ERRO_LOGIN ){
					redir ="login_"+actionString+"Loja.html?erro"+(request.getQueryString() != null ? "&" + request.getQueryString() : "");
				}else if( status == ERRO_LOGIN_INATIVO ){
					redir ="login_"+actionString+"Loja.html?inativo"+(request.getQueryString() != null ? "&" + request.getQueryString() : "");
				}else if( status == ERRO_REPETIDO){
					redir ="login_"+actionString+"Loja.html?repetido"+(request.getQueryString() != null ? "&" + request.getQueryString() : "");
				}else {
					redir = getRedir(request.getServletPath())+(request.getQueryString() != null ? "?" + request.getQueryString() : "");
				}
			}
			session.setAttribute("destino", ctx.get("path") + (ctx.get("query") != null ? "?" + ctx.get("query") : ""));
			ctx.put("path", "/" + redir);
			ctx.put("query", null);
			response.sendRedirect(montaURL(ctx));
			/* FIXME 4.2 */
			return;
		} else if (status == LOGIN_ADM) {
			if(ctx.get("admpath") != null && ctx.get("admpath").equals("/manager")){
				session.setMaxInactiveInterval(10800);
				chain.doFilter(request, response);
			}
			else{
				apagaCookie(response, "mmmUserName");
				apagaCookie(response, "mmmLogin");
				session.removeAttribute("USUARIO");
				session.removeAttribute("ADMINISTRADOR");
				ctx.put("path", "/login_LoginLoja.html");
				ctx.put("query", "erro");
				response.sendRedirect(montaURL(ctx));
				return;
			}
		} else if (status == ADM_PERMISSAO_RESTRITA) {
			AdministradorTO adm = (AdministradorTO) session.getAttribute("ADMINISTRADOR");
			ctx.put("admpath", null);
			ctx.put("path", "/" + urlPadraoAdmRestrito(adm));
			response.sendRedirect(montaURL(ctx));
			return;
		} else {
			try {
				chain.doFilter(request, response);
			} catch (Exception e) {
				e.printStackTrace();
				response.sendRedirect("404");
			}
		}		
	}

	private int defineStatus(HttpServletRequest request, HttpServletResponse response) {
		String action = getActionFromPath(request.getServletPath());
		String method = getMethodFromPath(request.getServletPath());
		String actionString = request.getParameter("action");
		String manter = request.getParameter("manter");
		String login = request.getParameter("login");
		String senha = request.getParameter("senha");
		String logar = request.getParameter("logar");
		String sair = request.getParameter("logout");
		HttpSession session = request.getSession();
		int status = NAO_AUTORIZADO;

		UsuarioTO usuario = (UsuarioTO)session.getAttribute("USUARIO");
//	    AfiliadoTO afiliado = (AfiliadoTO)session.getAttribute("AFILIADO");
	    AdministradorTO administrador = (AdministradorTO)session.getAttribute("ADMINISTRADOR");

	    // Se n�o tem usu�rio logado, nem tentando logar e nem tentando sair, verificar se tem cookie de login; XXX mudar de lugar
		if(usuario == null && logar == null && login == null && senha == null && sair == null && request.getCookies() != null){
			for(Cookie c : request.getCookies())
				if(c.getName().equals("mmmLogin")){
					try{
						login = c.getValue().split("#SPLIT#")[0];
						senha = c.getValue().split("#SPLIT#")[1];
						actionString = "Login";
						logar = "true";
						manter = "true";
					}
					catch(Exception e){
						login = null;
						senha = null;
						actionString = null;
						logar = null;
						apagaCookie(response, "mmmLogin");
					}
					break;
				}
		}

		/*
		if(administrador!=null && sair == null && checkRole(action, method, administrador.getTipo())){
			status = AUTORIZADO;
			// Verifica permissoes do administrador. "!checkRole" usado aqui para permitir que o adm, mesmo com permissoes restritas, consiga acessar a loja.
			if (!checkPermissaoAdm(action, administrador, session) && !checkRole(action, method, "CLIENTE")){
				status = ADM_PERMISSAO_RESTRITA; //Adminsitrador tentou acessar url nao contemplada por suas permissoes
			}
		} else if ((usuario != null || afiliado != null) && sair == null && logar == null && login == null && senha == null) {
			//USUARIO OU AFILIADO JAH LOGADO
			if ( (usuario != null && checkRole(action, method, usuario.getTipo())) || 
					(afiliado != null && checkRole(action, method, afiliado.getTipo()) )) {
				status = AUTORIZADO;
			} else {
				status = NAO_AUTORIZADO;
			}
			
		} else if (logar != null && login != null && senha != null){
			//USUARIO TEM COOKIE DE LOGIN AUTOM�TICO OU USUARIO LOGANDO
			//GABRIEL: ALTERA��O PARA PERMITIR LOGAR COM A SENHA EM QUALQUER FORMATO
			//usuario = mgr.getUsuario(login, Md5.getHash(senha.toLowerCase()));
			//OBS: Apenas o e-mail e o hash da senha tamb�m s�o aceitos. 
			if(actionString.equals("Login"))
				usuario = mgr.getUsuario(login, senha);
			else
				usuario = mgr.getUsuario(login, senha, "AFILIADO");
			
			if(usuario == null)
				apagaCookie(response, "mmmLogin");
			if (usuario != null && actionString.equals("Login") ){
				if(usuario.getAtivo() == Boolean.FALSE) {
					ClienteTO cliente =  mgrCliente.getCliente(login);
					if(cliente != null && cliente.getRepetido() != null && cliente.getRepetido() == true){
						Filtro filtroCliente = new Filtro();
						filtroCliente.setClazz(ClienteTO.class);
				    	ClienteTO exampleCliente = new ClienteTO();
				    	exampleCliente.setRemovido(false);
				    	exampleCliente.setAtivo(true);
				    	List<ClienteTO> listCliente;
				    	
				    	exampleCliente.setCpf(cliente.getCpf().replace(".", "").replace("-", "").replace("/", ""));
				    	filtroCliente.setExample(exampleCliente);
				    	listCliente = mgrCliente.getList(filtroCliente);
				    	
				    	if(listCliente.size() > 0){
				    		session.setAttribute("emailRepetido", listCliente.get(0).getEmail());
				    		status = ERRO_REPETIDO;
				    	} else {
				    		session.setAttribute("erros", "login.bloqueado");
							status = ERRO_LOGIN_INATIVO;
				    	}
					}
					else {
						session.setAttribute("erros", "login.bloqueado");
						status = ERRO_LOGIN_INATIVO;
					}
					apagaCookie(response, "mmmLogin");
					apagaCookie(response, "mmmUserName");
				} else if (usuario instanceof AfiliadoTO) {
					session.setAttribute("erros", "errors.loginErroPerfil");
					status = ERRO_LOGIN;
				} else {
					session.setAttribute("USUARIO", usuario);
					
					Date hoje = new Date();
					if("ADMINISTRADOR".equals(usuario.getTipo())) {
						session.setAttribute("ADMINISTRADOR", usuario);
						status = (checkPermissaoAdm(action, (AdministradorTO)usuario, session)) ? status : ADM_PERMISSAO_RESTRITA;
					} else if ("CLIENTE".equals(usuario.getTipo()) ) {
						addCookie(response, "mmmCliente", usuario.getId().toString(), 60*60*24*90); // 3 meses
						try {
							Long idUserFidelidade = ((ClienteTO)usuario).getIdAmigoFidelidade();
							if(idUserFidelidade == null) {
								idUserFidelidade = mgr.getIdAmigoFidelidade(usuario.getEmail());
							}
							if (idUserFidelidade != null) {
								session.setAttribute("ID_FIDELIDADE", idUserFidelidade);
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					} else if( ((ClienteTO)usuario).getIdPontoAfiliado() != null &&
							(((hoje.getTime() - usuario.getDataCriacao().getTime())/(1000*60*60*24)) < 60) ) { 
						session.setAttribute("ID_PONTO_AFILIADO", ((ClienteTO)usuario).getIdPontoAfiliado());
						
					}	
					
					//VERIFICAR SE O DESTINO AP�S O LOGIN DE USU�RIO � PERMITIDO, A NAO SER QUE O ERRO ACUSADO A PRINCIPIO TENHA SIDO DE PERMISSAO (ESTE ERRO DEVE SER MANTIDO E TRATADO, 'NAO_AUTORIZADO' NAO CONTEMPLA O REDIRECIONAMENTO NECESSARIO DESTE CASO)
					if (status != ADM_PERMISSAO_RESTRITA){
						if("ADMINISTRADOR".equals(usuario.getTipo()))
							status = checkRole(action, method, usuario.getTipo()) ? LOGIN_ADM : NAO_AUTORIZADO;
						else
							status = checkRole(action, method, usuario.getTipo()) ? LOGIN : NAO_AUTORIZADO;
					}
					
					session.removeAttribute("destino"); // XXX Acho que n�o precisa disso n�o

					addCookie(response, "mmmUserName", usuario.getApelido(), 60*60*24*365); // 1 ano
					if(manter != null && (!usuario.getTipo().equals("ADMINISTRADOR") || LojaConfigTO.isLocalHost))
						addCookie(response, "mmmLogin", usuario.getLogin()+"#SPLIT#"+usuario.getSenha(), 60*60*24*30); // 1 m�s
					else
						apagaCookie(response, "mmmLogin");
				}
			} else {
				if(usuario != null && actionString.equals("Afiliado") && usuario instanceof AfiliadoTO ) {
					session.setAttribute("AFILIADO", (AfiliadoTO)usuario);
					session.removeAttribute("destino");
					if("ADMINISTRADOR".equals(usuario.getTipo()))
						status = checkRole(action, method, usuario.getTipo()) ? LOGIN_ADM : NAO_AUTORIZADO;
					else
						status = checkRole(action, method, usuario.getTipo()) ? LOGIN : NAO_AUTORIZADO;
				}
				else if (usuario instanceof ClienteTO || usuario instanceof AdministradorTO) {
					session.setAttribute("erros", "errors.loginErroPerfil");
					status = ERRO_LOGIN;
				}
				else {
					request.setAttribute("erros","login.erro");
					status = ERRO_LOGIN;
				}	
			}
		} else if(sair != null){
			//USUARIO SAINDO
			session.invalidate();
			apagaCookie(response, "mmmCliente");
			apagaCookie(response, "mmmLogin");
			apagaCookie(response, "mmmUserName");
			status = SAIR;
		} else {
			//ACESSO COMUM NAO LOGADO
			if (checkRole(action, method))
				status = AUTORIZADO;
			else {
				session.removeAttribute("USUARIO"); // XXX Acho que nunca cai aqui quando tem um usuario na sess�o, ent�o pode tirar essa linha
				status = NAO_AUTORIZADO; 
			}
		}
		*/
		return status;
	}

	private String montaURL(Map<String, String> ctx) {
		String url = "";
		Map<String, String> ctxPadrao = HTTP_PARCERIA.get(ctx.get("parceria"));
		Map<String, String> ctxSeguro = HTTPS_PARCERIA.get(ctx.get("parceria"));
		
		// http://www.isnow.com.br || http://localhost
		url += ctx.get("scheme") + "://" + ctx.get("name");
		
		// :80 || :443
		if(!ctx.get("port").equals(ctxPadrao.get("port")) && !ctx.get("port").equals(ctxSeguro.get("port")))
			url += ":" + ctx.get("port");
		
		// /isnow
		if(ctx.get("prepath") != null)
			url += ctx.get("prepath");
		
		// /minhacasa
		if(ctx.get("parceria") != null && !ctx.get("parceria").isEmpty())
			url += "/" + ctx.get("parceria");
		
		// /manager
		if(ctx.get("admpath") != null)
			url += ctx.get("admpath");
		
		// /produto/cama-casal || /index.html || /
		url += ctx.get("path");
		
		// ?page=1&sort=2
		if(ctx.get("query") != null && !ctx.get("query").isEmpty())
			url += "?" + ctx.get("query");
		
		return url;
	}

	private void defineCTX(HttpServletRequest request, Map<String, String> ctx) {
		ctx.put("scheme", request.getScheme());
		ctx.put("name", request.getServerName());
		ctx.put("port", request.getServerPort() + "");
		ctx.put("path", request.getRequestURI());
		ctx.put("query", request.getQueryString());
		ctx.put("ip", request.getLocalAddr() != null ? request.getLocalAddr() : "");
		ctx.put("agent", request.getHeader("X-Requested-With") != null ? request.getHeader("X-Requested-With") : "");
		ctx.put("parceria", request.getAttribute("parceria") != null ? request.getAttribute("parceria").toString() : null);
		
		defineParceria(ctx);
		defineLocal(ctx);
	}
	
	private void defineParceria(Map<String, String> ctx) {
		if(ctx.get("path").contains("/isnow")){
			ctx.put("path", ctx.get("path").replace("/isnow", ""));
			ctx.put("prepath", "/isnow");
		}
		if(ctx.get("path").contains("/minhacasa") || ctx.get("name").endsWith("lojaminhacasa.com.br")){
			ctx.put("path", ctx.get("path").replace("/minhacasa", ""));
			ctx.put("parceria", "minhacasa");
		}
		if(ctx.get("path").contains("/manager")){
			ctx.put("path", ctx.get("path").replace("/manager", ""));
			ctx.put("admpath", "/manager");
		}
	}

	private void defineLocal(Map<String, String> ctx) {
//		if(ctx != null && ctx.get("name") != null && ctx.get("name").equals("localhost")) //FIXME Verificar ambientePadrao
//			LojaConfigTO.isLocalHost = true;
//		else
//			LojaConfigTO.isLocalHost = false;
	}
	
	private boolean redirect(HttpServletResponse response, Map<String, String> ctx) throws IOException {
		boolean redir = false;
		if(redirectWWW(ctx))
			redir = true;
		if(redirectScheme(ctx))
			redir = true;
		if(redir){
			response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
			response.setHeader("Location", montaURL(ctx));
			return redir;
		}
		return redir;
	}
	private boolean redirectWWW(Map<String, String> ctx) {
//		if(LojaConfigTO.isLocalHost)
//			return false;
		
		if(ctx.get("name").startsWith("www"))
			return false;
		else
			ctx.put("name", "www." + ctx.get("name"));
		
		return true;
	}
	private boolean redirectScheme(Map<String, String> ctx){
//		if(LojaConfigTO.isLocalHost)
//			return false;
		if(inheritedScheme(ctx))
			return false;
		
		Boolean security_page = false;
		Map<String, String> ctxHTTP = HTTP_PARCERIA.get(ctx.get("parceria"));
		Map<String, String> ctxHTTPS = HTTPS_PARCERIA.get(ctx.get("parceria"));		
		
		if(checkRole(getActionFromPath(ctx.get("path")), getMethodFromPath(ctx.get("path")))){
			// P�ginas que sempre devem ser seguras para qualquer usu�rio (TODOS)
			security_page = ctx.get("path").endsWith("login_LoginLoja.html") ||
							ctx.get("path").endsWith("novo_ClienteLoja.html") ||
							ctx.get("path").endsWith("save_ClienteLoja.html") ||
							ctx.get("path").endsWith("comprarAgora_Loja.html") ||
							ctx.get("path").endsWith("login_AfiliadoLoja.html") ||
							//ctx.get("path").endsWith("edit_PesquisaLoja.html") ||
							ctx.get("path").endsWith("edit_PesquisaNPSLoja.html") ||
							ctx.get("path").endsWith("edit_RecuperacaoSenha.html") ||
							ctx.get("path").endsWith("save_RecuperacaoSenha.html") ||
							ctx.get("path").endsWith("autenticaAmmmigo_Loja.html") ||
							ctx.get("path").endsWith("emitirSegundaVia_PagamentoLoja.html") ||
							ctx.get("path").contains("wsIntegracao") ||
							ctx.get("path").contains("retornoEnvio2ExternoHttp");
		}
		else{
			// Como a p�gina � restrita tem que sempre ser segura
			security_page = true;
		}
		
		if(!security_page && !(ctxHTTP.get("scheme").equals(ctx.get("scheme")) && ctxHTTP.get("name").equals(ctx.get("name")))){
			//request.getSession().setAttribute("PROTOCOLO", ctxPadrao.get("scheme"));
			ctx.put("scheme", ctxHTTP.get("scheme"));
			ctx.put("name", ctxHTTP.get("name"));
			ctx.put("port", ctxHTTP.get("port"));
			return true;
		}
		if(security_page && !(ctxHTTPS.get("scheme").equals(ctx.get("scheme")) && ctxHTTPS.get("name").equals(ctx.get("name")))){
			//request.getSession().setAttribute("PROTOCOLO", ctxSeguro.get("scheme"));
			ctx.put("scheme", ctxHTTPS.get("scheme"));
			ctx.put("name", ctxHTTPS.get("name"));
			ctx.put("port", ctxHTTPS.get("port"));
			return true;
		}
		
		return false;
	}

	/* Verifica se o administrador logado esta acessando somente paginas contempladas por suas permissoes */
	private boolean checkPermissaoAdm(String caminho, AdministradorTO adm, HttpSession session){
		session.setAttribute("admRestrito", true);
		if (adm != null){
//			if (adm.getApenasMinhaCasa() != null && adm.getApenasMinhaCasa()){
//				return caminho.equals("Painel");
//			}
//			if (adm.getApenasNewsletter() != null && adm.getApenasNewsletter()){
//				return caminho.equals("MailMarketing");
//			} 
//			if ((adm.getIsMontador() != null && adm.getIsMontador()) || (adm.getIsTransportador() != null && adm.getIsTransportador())){
//				return caminho.equals("OrdemEntregaMontagem");
//			}
		}
		session.removeAttribute("admRestrito");
		return true;
	}
	
	/* Retorna a url principal a qual um adm com permissoes restritas pode acessar.
	 * Retorna null se o administrador nao possui restricoes
	 * */
	private String urlPadraoAdmRestrito(AdministradorTO adm){
		String urlPadrao = null;
		if (adm != null){
//			if (adm.getApenasMinhaCasa() != null && adm.getApenasMinhaCasa()){
//				urlPadrao = "manager/execute_Painel.html";
//			}
//			if (adm.getApenasNewsletter() != null && adm.getApenasNewsletter()){
//				urlPadrao = "manager/list_MailMarketing.html";
//			}
//			if ((adm.getIsMontador() != null && adm.getIsMontador()) || (adm.getIsTransportador() != null && adm.getIsTransportador())){
//				urlPadrao = "manager/list_OrdemEntregaMontagem.html";
//			}
		}
		return urlPadrao;
	}
	
	// Todos
	private boolean checkRole(String action, String method){
		return checkRole(action, method, null);
	}
	// Perfil especificado
	private boolean checkRole(String action, String method, String perfil){
		String todos = "TODOS";
		if(perfil == null)
			perfil = todos;
		
		String propLinha = null;
		if (method != null) {
			String novoCaminho = method + "_" + action;
			propLinha = (String)securityMapping.get(novoCaminho);
		}
		if (propLinha == null) {
			propLinha = (String)securityMapping.get(action);
		}
		
		List<String> roles = null;
 		if(propLinha != null){
			StringTokenizer tipo = new StringTokenizer(propLinha,",");
			roles = new ArrayList<String>();
			while(tipo != null && tipo.hasMoreTokens()){
				String tok = tipo.nextToken();
				roles.add(tok);
			}
		}
 		
		return roles == null || roles.contains(perfil) || roles.contains(todos);
	}

	public String getActionFromPath(String servletPath){
		String action = "Inicio";
		try {
			if (servletPath.indexOf("_") != -1){
				action = servletPath.substring(servletPath.indexOf("_") + 1, servletPath.indexOf(".html"));
			} else {
				action = servletPath.substring(1, servletPath.indexOf(".html"));
			}
		} catch (Exception e) {
			//e.printStackTrace();
		}
		return action.replace("minhacasa/", "");
	}
	public String getMethodFromPath(String servletPath){
		String method = "";
		try {
			method = servletPath.substring(1, servletPath.indexOf("_"));
		} catch (Exception e) {
			//e.printStackTrace();
		}
		return method.replace("minhacasa/", "");
	}
	
	private void setCookie(HttpServletResponse response, String cookieName, String cookieContent, int cookieAge){
		Cookie c = new Cookie(cookieName, cookieContent);
		c.setPath("/");
		if(cookieAge >= 0)
			c.setMaxAge(cookieAge);
		response.addCookie(c);
	}
	private void addCookie(HttpServletResponse response, String cookieName, String cookieContent){
		setCookie(response, cookieName, cookieContent, -1);
	}
	private void addCookie(HttpServletResponse response, String cookieName, String cookieContent, int cookieAge){
		setCookie(response, cookieName, cookieContent, cookieAge);
	}
	private void apagaCookie(HttpServletResponse response, String cookieName){
		setCookie(response, cookieName, "", 0);
	}
	
	private boolean useSecurityRedirect(Map<String, String> ctx) {
		if(ctx.get("path").endsWith(".html"))
			return true;
		if(ctx.get("path").contains("."))
			return false;
		return true;
	}
	
	private boolean useSecurityFilter(Map<String, String> ctx) {
		if(ctx.get("path").contains("dojo"))
			return false;
		if(ctx.get("path").endsWith(".html"))
			return true;
		return false;
	}

	private boolean inheritedScheme(Map<String, String> ctx) {
		if(ctx.get("agent").equals("XMLHttpRequest"))
			return true;
		if(ctx.get("path").startsWith("/tinyfck/"))
			return true; 
		if(ctx.get("path").equals("/timeoutRedirectLogin_LoginLoja.html"))
			return true;
		return false;
	}
	
	private void miscOsklen(HttpServletRequest request){
		//Parceria com a Okslen
	    String Osklen = request.getParameter("parceria");
	    if("osklen".equals(Osklen)){
			request.getSession().setAttribute("osklen", "true");
		}
	    
	    //Removo a variavel de sessao osklen caso ela esteja setada e se a URL estiver em alguma das telas de categorias/produtos.
	    String URL = request.getRequestURL().toString();
	    String manterOsklen = (String)request.getSession().getAttribute("manterOsklen");
		if(request.getSession().getAttribute("osklen") != null && !(manterOsklen != null && manterOsklen.equals("true")) && (URL.contains("index") || URL.contains("ambientes") || URL.contains("moveis") || URL.contains("conjuntos") || URL.contains("linhas") || URL.contains("produto") || URL.contains("decoracao"))){
			request.getSession().removeAttribute("osklen");
		}
		request.getSession().removeAttribute("manterOsklen");
	}
	
	private void miscApple(HttpServletRequest request){	
		if(request.getSession().getAttribute("appleMobile") == null && (request.getHeader("user-agent").contains("iPad") || request.getHeader("user-agent").contains("iPhone"))) {
			request.getSession().setAttribute("appleMobile", true);
		}
	}

	private void miscAbraco(HttpServletRequest request) {
		/*
		if (request.getServletPath().contains("recomendacaoAbraco_Loja")){
			request.getSession().setAttribute("abraco", "true");
		}
		*/
	}

	private boolean miscAcessoAdmCliente(HttpServletRequest request, HttpServletResponse response, Map<String, String> ctx) {
		HttpSession session = request.getSession();
	    UsuarioTO usuario = (UsuarioTO)session.getAttribute("USUARIO");
	    AdministradorTO administrador = (AdministradorTO)session.getAttribute("ADMINISTRADOR");
	    
		if(usuario != null && administrador != null && request.getParameter("trocarUsuario") != null){
			// Configura a sess�o e retorna qual a parceria
			String parceriaUsuario = miscAcessoCliente(request, response, administrador, usuario);
			ctx.put("admpath", null);
			// Verifica se a parceria � minhacasa ou n�o (necess�rio para pagar comiss�o da minhacasa)
			if (parceriaUsuario != null && parceriaUsuario.equals("minhacasa")){
				if(ctx.get("parceria") != null && ctx.get("parceria").equals("minhacasa"))
					return false;
				else{
					ctx.put("parceria", "minhacasa");
					return true;
				}
			}
		}
		
		if(usuario !=null && request.getParameter("acaoVoltarADM")!=null && session.getAttribute("CARRINHOADM") != null){
			sairAcessoCliente(request, usuario);
			apagaCookie(response, "mmmUserName");
		}
		return false;
	}

	private String miscAcessoCliente(HttpServletRequest request, HttpServletResponse response, AdministradorTO administrador, UsuarioTO usuario) {
		/*
		HttpSession session = request.getSession();
		session.setAttribute("IdADM", administrador.getId().toString());
		session.setAttribute("CARRINHOADM", true);
		usuario = mgr.getUsuario(request.getParameter("idUsuario"));
		session.setAttribute("USUARIO", usuario);
		session.removeAttribute("PEDIDO");
		session.removeAttribute("PASSOS");
		
		String parceriaUsuario = ((ClienteTO)usuario).getParceria();
		List<PedidoTO> listPedidos = mgrPedido.getListPedidosCliente((ClienteTO)usuario);
		if(listPedidos != null && listPedidos.size() > 0 && listPedidos.get(0) != null){
			parceriaUsuario = listPedidos.get(0).getParceria();
		}
		addCookie(response, "mmmUserName", usuario.getApelido());
		
		return parceriaUsuario;
		 */
		return null;
	}

	private void sairAcessoCliente(HttpServletRequest request, UsuarioTO usuario) {
		HttpSession session = request.getSession();
//		usuario = mgr.getUsuario((String) session.getAttribute("IdADM"));
		session.setAttribute("USUARIO", usuario);
		session.removeAttribute("CARRINHOADM");
		session.removeAttribute("PEDIDO");
		session.removeAttribute("PASSOS");
	}
	
/*
	private void debug(HttpServletRequest request){
		System.out.println("CONTENT: "+request.getContentType());
		System.out.println("URL:" + request.getRequestURL());
		System.out.println("CAMINHO:" + request.getServletPath());
		
		System.out.println("************* HTTP - "+request.getMethod()+" *************");
		Enumeration hds = request.getHeaderNames();
		while(hds.hasMoreElements()){
			String hd = (String)hds.nextElement();
			System.out.println(hd+" = "+request.getHeader(hd));			
		
		}
		hds = request.getParameterNames();
		while(hds.hasMoreElements()){
			String hd = (String)hds.nextElement();
			System.out.println(hd+" = "+request.getParameter(hd));			
		
		}

		System.out.println("************* FIM  *************");
	}
	private void debug(HttpSession session){
		System.out.println("********** SESSION ************");
		
		System.out.println("ADMINISTRADOR: "+(session.getAttribute("ADMINISTRADOR")!=null ? ((AdministradorTO)session.getAttribute("ADMINISTRADOR")).getNome() : "null" ));
		System.out.println("      USUARIO: "+(session.getAttribute("USUARIO")!=null ? ((UsuarioTO)session.getAttribute("USUARIO")).getNome() + "("+session.getAttribute("USUARIO").getClass()+")" : "null" ));		
		
//		Enumeration hds = session.getAttributeNames();
//		while(hds.hasMoreElements()){
//			String hd = (String)hds.nextElement();
//			System.out.println((session.getAttribute(hd)!=null ? "Existente":"     NULL:")+" = "+hd);			
//		}
//	
		System.out.println("************* SESSION FIM  *************");
	}
*/
}